Список Задач + SQLite + Interface + DI
➡️Ссылка на репозиторий с кодом этого урока
Добавление инверсии зависимостей - это удобно
Теперь самый главный момент, который демонстрирует всю мощь проделанной ранее работы по рефакторингу.
Чтобы перейти на SQLite теперь нужно изменить всего лишь одну строку в main.dart.
Файл main.dart
void main() {
// Важно! Инициализируем Flutter перед работой с плагинами
WidgetsFlutterBinding.ensureInitialized();
runApp(
// Оборачиваем приложение в ChangeNotifierProvider
// Создаём экземпляр ViewModel и передаём вниз по дереву
ChangeNotifierProvider(
create: (context) => ToDoViewModel(
// 👉 Теперь внедряем новый сервис SqliteService
storageService: SqliteService(),
),
child: const ToDoApp(),
),
);
}
WidgetsFlutterBinding.ensureInitialized()
-
Эта строка кода является "клеем" между фреймворком Flutter и нативным кодом платформы (Swift/Kotlin)
-
runApp()обычно сам вызывает инициализацию этого "клея". Но если нужно выполнить какую-то операцию, требующую связи с нативной частью, до запускаrunApp(), нужно сделать это вручную.
Используем этот метод когда функция main является асинхронной (async) и содержит await для вызовов, которые обращаются к платформе
- Инициализация Firebase: `await Firebase.initializeApp();
- Доступ к
SharedPreferences: `await SharedPreferences.getInstance(); - Получение пути к базе данных
sqflite: `await getDatabasesPath();
Все эти операции используют "платформенные каналы" для общения с нативным кодом. WidgetsFlutterBinding.ensureInitialized() гарантирует, что эти каналы готовы к работе еще до того, как Flutter начнет рисовать первый виджет
Это хорошая практика чтобы избежать потенциальных проблем в будущем.
Демонстрация работы приложения
Приложение работает абсолютно так же, как и раньше! Вы можете добавлять, изменять и удалять задачи. Но теперь все данные хранятся не в файле SharedPreferences, а в структурированной базе данных SQLite на вашем устройстве.
ToDoViewModel, ToDoScreen и другие виджеты даже не подозревают о смене источника данных. Они продолжают общаться через интерфейс IStorageService, что делает архитектуру по-настоящему гибкой и масштабируемой.
